﻿using CQIE.JonJack.Models;
using CQIE.JonJack.Models.Tabels;
using CQIE.JonJack.SplLibraryService._IAdmainService;
using CQIE.JonJack.UtilitySource;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Polly.Timeout;
using Polly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Net;

namespace CQIE.JonJack.SplLibraryService.AdmainServiceImpl
{
    //在实现里为每一个接口创建队列，分别与后台微服务对接
    public class AdmainServiceImpl : IAdmainService
    {
        private readonly _DbContext Db;
        private readonly IOptionsSnapshot<JWTSettings> jwtSettingsOpt;
        //请求对象
        private static readonly HttpClient client = new HttpClient();

        private IDistributedCache RedisCache;
        private readonly PollyServices pollyServices;
        private Policy<string> _policy;
        private AsyncTimeoutPolicy policy;
        private Policy<string> fallBackPolicy;
        private Policy<string> wrapPolicy;
        private Policy<string> circuiBreaker;
        

        public AdmainServiceImpl(_DbContext db, IOptionsSnapshot<JWTSettings> jwtSettingsOpt, IDistributedCache redisCache, PollyServices pollyServices)
        {
            Db = db;
            this.jwtSettingsOpt = jwtSettingsOpt;
            RedisCache = redisCache;
            this.pollyServices = pollyServices;

            //执行polly操作
            //pollyServices.TestCircuitBreaker();
            //降级
            _policy = pollyServices.TestRetry2();//重试
            policy = pollyServices.TestTimeOut();//超时
            fallBackPolicy = pollyServices.TestFallback();//回退
            wrapPolicy = pollyServices.TestWrapPolicy();//组合策略
            circuiBreaker = pollyServices.TestWrapPolicy_2();//熔断降级
        }


        public bool Audit(string uid, bool ac)
        {
            circuiBreaker.Execute(() =>
            {
                User user = Db.User.Where(u => u.SchoolNumber == uid).Single();
                if (ac)
                {//通过
                    user.IsAccess = ac;
                }
                else
                {//不通过
                    Db.User.Remove(user);
                }


                Db.SaveChanges();

                return "Operation completed successfully.";
            });


            return true;

        }

        public string getAllApplicationList()
        {
            List<User> users = new();

            circuiBreaker.Execute(() =>
            {
                users = Db.User.Where(u => u.IsAccess == false).ToList();

                return "Operation completed successfully.";
            });

            var js = users.Select(u => new
            {
                name=u.Name,
                schoolNumber=u.SchoolNumber,
            });

            string jsonString = JsonConvert.SerializeObject(js);
            return jsonString;

        }

        public string getReader()
        {
            List<User> users = new();
            circuiBreaker.Execute(() =>
            {
                users=Db.User.Where(u => u.IsAccess == true).ToList();

                return "Operation completed successfully.";
            });

            

            var js = users.Select(u => new
            {
                name = u.Name,
                schoolNumber = u.SchoolNumber,
                isDisabled=u.IsDisabled
            });

            string jsonString = JsonConvert.SerializeObject(js);
            return jsonString;
        }

        public bool ReaderManage(string uid, bool ac)
        {
            User user = new();

            circuiBreaker.Execute(() =>
            {
                user = Db.User.Where(u => u.SchoolNumber == uid).Single();

                return "Operation completed successfully.";
            });

            user.IsDisabled = ac;
           

            Db.SaveChanges();

            return true;
        }
    }
}
